package com.alinesno.cloud.gateway.core.dispather.socket.coder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alinesno.cloud.gateway.core.dispather.socket.bean.RequestMessageBean;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.util.CharsetUtil;

/**
 * 
 *  该类是负责编码 RequestMessageBean 为一系列字节 <br/>
 * 	转换的 key 和实际请求的 body 到字节数组 <br/>
 * 	计算 body 大小 <br/>
 * 	写幻数到 ByteBuf 字节 <br/>
 * 	写 opCode 作为字节 <br/>
 * 	写 key 长度z作为 short <br/>
 * 	编写额外的长度作为字节 <br/>
 * 	写数据类型,这总是0,因为目前不是在 Memcached,但可用于使用 后来的版本 <br/>
 * 	为保留字节写为 short ,后面的 Memcached 版本可能使用 <br/>
 * 	写 body 的大小作为 long <br/>
 * 	写 opaque 作为 int <br/>
 * 	写 cas 作为 long。这个是头文件的最后部分，在 body 的开始 <br/>
 *  编写额外的 flag 和到期时间为 int <br/>
 * 	写 key <br/>
 * 	这个请求完成后 写 body
 * <br/>
 * 编码器 使用 Netty 的 ByteBuf 处理请求，编码 MemcachedRequest 成一套正确排序的字节。详细步骤为：
	写幻数字节。
	写 opcode 字节。
	写 key 长度(2字节)。
	写额外的长度(1字节)。
	写数据类型(1字节)。
	为保留字节写 null 字节(2字节)。
	写 body 长度(4字节- 32位整数)。
	写 opaque(4个字节,一个32位整数在响应中返回)。
	写 CAS(8个字节)。
	写 额外的(flag 和 到期,4字节)= 8个字节
	写 key
	写 值
 * 
 * @author LuoAnDong
 * @since 2019年9月21日 下午8:54:08
 * @author LuoAnDong
 * @since 2019年9月21日 下午8:57:14
 */
public class RequestMessageEncoder extends MessageToByteEncoder<RequestMessageBean> { //1

	private static final Logger log = LoggerFactory.getLogger(RequestMessageEncoder.class) ; 
	
    @Override
    protected void encode(ChannelHandlerContext ctx, RequestMessageBean msg, ByteBuf out) throws Exception {  //2
   
    	log.debug("消息发出:{} , data:{}" , msg.getMagic() , msg.getData());
    	
        byte[] magic = msg.getMagic().getBytes(CharsetUtil.UTF_8) ; 
        byte[] body = msg.getData().getBytes(CharsetUtil.UTF_8);
        byte[] length = String.valueOf(body.length).getBytes(CharsetUtil.UTF_8) ; 
        
        out.writeBytes(magic);
        out.writeBytes(length);
        out.writeBytes(body);
    }
}